﻿using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace UtfprLibrary.Windows.Forms.ComponentModel {
    public class UtfprToolStripRenderer : ToolStripProfessionalRenderer {
        protected override void OnRenderOverflowButtonBackground(ToolStripItemRenderEventArgs e) {
            var bounds = new Rectangle(Point.Empty, e.Item.Size);

            DrawStringRectangle(e.Graphics, bounds);

            var gradientBegin = e.ToolStrip.BackColor;
            var gradientEnd = e.ToolStrip.BackColor;
            var button = e.Item as ToolStripOverflowButton;

            if (button.Pressed) {
                gradientBegin = SystemColors.InactiveBorder;
                gradientEnd = SystemColors.InactiveCaption;
                FillGradient(e.Graphics, bounds, gradientBegin, gradientEnd);
                DrawStringRectangle(e.Graphics, bounds);
            } else if (button.Selected) {
                gradientBegin = SystemColors.ControlLightLight;
                gradientEnd = SystemColors.ControlLight;
                FillGradient(e.Graphics, bounds, gradientBegin, gradientEnd);
                DrawStringRectangle(e.Graphics, bounds);
            }
        }

        #region methods

        private void FillGradient(Graphics graphics, Rectangle rectangle, Color gradientBegin, Color gradientEnd) {
            using (Brush brush = new LinearGradientBrush(
                rectangle,
                gradientBegin,
                gradientEnd,
                LinearGradientMode.Vertical)) {
                FillRoundRect(
                    graphics,
                    brush,
                    rectangle.X,
                    rectangle.Y,
                    rectangle.Width - 2,
                    rectangle.Height - 2,
                    3F);

                DrawRoundRect(
                    graphics,
                    SystemPens.ActiveBorder,
                    rectangle.X,
                    rectangle.Y,
                    rectangle.Width - 2,
                    rectangle.Height - 2,
                    3F);
            }

        }

        private void DrawStringRectangle(Graphics g, Rectangle rectangle) {
            var drawString = ">>";
            var drawFont = new Font("Arial", 7F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(0)));
            var drawBrush = new SolidBrush(Color.Black);
            var drawRectangle = new Rectangle(
                rectangle.X,
                rectangle.Y + rectangle.Height / 4,
                rectangle.Width,
                rectangle.Height - rectangle.Height / 4);


            g.DrawString(drawString, drawFont, drawBrush, drawRectangle);
        }

        private void DrawRoundRect(Graphics g, Pen p, float x, float y, float width, float height, float radius) {
            using (var gp = new GraphicsPath()) {
                gp.AddLine(x + radius, y, x + width - (radius * 2), y); // Line
                gp.AddArc(x + width - (radius * 2), y, radius * 2, radius * 2, 270, 90); // Corner

                gp.AddLine(x + width, y + radius, x + width, y + height - (radius * 2)); // Line
                gp.AddArc(x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90); // Corner

                gp.AddLine(x + width - (radius * 2), y + height, x + radius, y + height); // Line
                gp.AddArc(x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90); // Corner

                gp.AddLine(x, y + height - (radius * 2), x, y + radius); // Line
                gp.AddArc(x, y, radius * 2, radius * 2, 180, 90); // Corner

                gp.CloseFigure();
                g.DrawPath(p, gp);
            }
        }

        private void FillRoundRect(Graphics g, Brush b, float x, float y, float width, float height, float radius) {
            using (var gp = new GraphicsPath()) {
                gp.AddLine(x + radius, y, x + width - (radius * 2), y); // Line
                gp.AddArc(x + width - (radius * 2), y, radius * 2, radius * 2, 270, 90); // Corner

                gp.AddLine(x + width, y + radius, x + width, y + height - (radius * 2)); // Line
                gp.AddArc(x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90); // Corner

                gp.AddLine(x + width - (radius * 2), y + height, x + radius, y + height); // Line
                gp.AddArc(x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90); // Corner

                gp.AddLine(x, y + height - (radius * 2), x, y + radius); // Line
                gp.AddArc(x, y, radius * 2, radius * 2, 180, 90); // Corner

                gp.CloseFigure();
                g.FillPath(b, gp);
            }
        }

        #endregion
    }
}
